#include "BestQuoteModel.h"

#include <bondlib/BestQuote/CBondFilter.h>
#include <bondlib/BestQuote/CBrokerKeyList.h>
#include <bondlib/SSVContainer.h>

#define SSM_METRICS  //

RowRecordKeyMap::RowRecordKeyMap() { Clear(); }
RowRecordKeyMap::~RowRecordKeyMap() {}
void RowRecordKeyMap::Clear() {
  m_max_row = -1;
  m_screen_bonds.clear();
}
void RowRecordKeyMap::Add(int row, const BrokerKey& bond) {
  m_screen_bonds.insert(BondRowMap::value_type(row, bond));
  m_max_row = m_max_row < row ? row : m_max_row;
}

int RowRecordKeyMap::GetRowCount() { return m_screen_bonds.size(); }
bool RowRecordKeyMap::GetBondKey(int row, BrokerKey& bond) {
  BondRowMap::iterator it = m_screen_bonds.find(row);
  if (it != m_screen_bonds.end()) {
    bond = it->second;
    return true;
  }
  return false;
}

BestQuoteModel::BestQuoteModel(const CBrokerUnit& stUnit,
                               const CSortInfoManager& sortInfo)
    : m_broker(stUnit), m_keys(0), m_sort_attend(false) {
  m_keys = new CBrokerKeyList(sortInfo, stUnit.m_brokerID);
  m_bond_filter = new CBondFilter();
}

BestQuoteModel::~BestQuoteModel() {
  if (m_keys) {
    delete m_keys;
    m_keys = 0;
  }
  if (m_bond_filter) {
    delete m_bond_filter;
    m_bond_filter = 0;
  }
}

void BestQuoteModel::UpdateBrokerList() {
  m_expandBroker.clear();
  const CBrokerList& brokerList =
      SSUserAccountManager::instance().GetReadonlyBroker();
  const std::vector<int>& sortID = brokerList.GetSortKey();
  for (int i = 0; i < (int)sortID.size(); i++) {
    int brokerId = sortID[i];
    const CBrokerUnit& unstUnitit = brokerList.GetBrokerUnit(brokerId);
    if (!CBrokerList::IsValidBroker(brokerId)) continue;
    if (!unstUnitit.m_enableFlag_BOND && !unstUnitit.m_enableFlag_NCD) continue;
    if (brokerId != 98)
      m_expandBroker.push_back(brokerId);  // 需展示出森浦外所有broker
  }
}

CSortInfoManager& BestQuoteModel::GetSortInfo() {
  return m_keys->GetSortInfo();
}

const CSortInfoManager& BestQuoteModel::GetSortInfo() const {
  return m_keys->GetSortInfo();
}

int BestQuoteModel::GetRowCount() { return m_keys->GetRowCount(); }

void BestQuoteModel::GetRecordKeys(int row, int count, CBrokerKeyVector& keys) {
  GetRecordKeysImpl(row, count, keys);
}
void BestQuoteModel::GetScreenKeys(int row, int count, CBrokerKeyVector& keys) {
  GetRecordKeysImpl(row, count, keys);
}
void BestQuoteModel::GetRecordKeysImpl(int row, int count,
                                       CBrokerKeyVector& keys) {
  if (count > 0) {
    BrokerKeyInfo* bkis = (BrokerKeyInfo*)alloca(count * sizeof(BrokerKeyInfo));
    memset(bkis, 0, count * sizeof(BrokerKeyInfo));
    int nsize = m_keys->GetRecordKeys(row, count, bkis);
    for (int i = 0; i < nsize; i++) {
      BrokerKeyInfo& bki = bkis[i];
      char buf[32] = {0};
      FMTBUF(buf, "%d", bki.m_nBrokerId);
      keys.push_back(BrokerKey(buf, bki.m_nIndex));
    }
  }
}

bool BestQuoteModel::IsExist(const BrokerKey& key) {
  BrokerKeyInfo bki(key);
  return m_keys->IsExist(bki);
}
int BestQuoteModel::GetVersion(const BrokerKey& key) {
  BrokerKeyInfo bki(key);
  return m_keys->GetVersion(bki);
}
void BestQuoteModel::ReloadRecords(FilterCondition& stTemp,
                                   std::list<std::string>& stlBrokerID,
                                   bool bAllTab, const QString& strGroupID) {
  m_expandedBond.clear();
  if (stTemp.m_nFocusType == 0 || stTemp.m_nFocusType == 1) {
    ReloadRecordsByFilter(stTemp.stBlh, stTemp.nSearchType,
                          stTemp.strSearch.toLocal8Bit().data(), bAllTab);
  } else {
    /*
    CBondAttentionMap mapAtt;
    AfxGetBondAttention().GetBondAttentionByGroupID(SSW2A(strGroupID), mapAtt);
    ReloadRecordsByAttention(stTemp.stBlh, mapAtt.m_map, stlBrokerID, bAllTab,
    stTemp.bNeedFilter);
    */
  }

  log_debug("ReloadRecords");
}
void BestQuoteModel::ReloadRecordsBySearch(
    CBondContainer::FilterTypes type, const char* strSearch,
    const std::list<std::string>& brokers) {
  SSM_METRICS("");
  // 从新从BondContainer中载入数据,需要重新排序,重新显示在虚表中
  BLHCONDITION condStr;
  CBondSourceStatic source(type, strSearch);
  // m_bond_filter->SetCondition(&condStr,false);//SEE CSSVContainer::Retrieve
  // 1055
  m_bond_filter->SetCondition(0, false);
  m_bond_filter->SetBrokers(brokers);
  m_keys->Reloads(&source, m_bond_filter);
}

void BestQuoteModel::ReloadRecordsByFilter(BLHCONDITION& blh, int nType,
                                           const char* szSearch, bool all) {
  SSM_METRICS("");
  CBondSourceAvailable source(blh);
  source.SetSearch(nType, szSearch);
  m_bond_filter->SetCondition(&blh, all);
  m_keys->Reloads(&source, m_bond_filter);
}

bool BestQuoteModel::UpdateBestPricePush(
    BLHCONDITION& condStr, const std::list<xQBBestPriceUnit_c>& qblist) {
  SSBrokerKeyVector vct_result, vct_resdel;

  CSSVContainer::availableBond().UpdateBestPricePush(condStr, vct_result,
                                                     vct_resdel, qblist, true);
  m_keys->Update(vct_result.m_vct, vct_resdel.m_vct);
  return !vct_result.m_vct.empty() || !vct_resdel.m_vct.empty();
}
bool BestQuoteModel::CheckExistBestPricePush(
    BLHCONDITION& condStr, const std::list<xQBBestPriceUnit_c>& qblist) {
  SSBrokerKeyVector vct_result, vct_resdel;

  CSSVContainer::availableBond().UpdateBestPricePush(condStr, vct_result,
                                                     vct_resdel, qblist, true);
  if (vct_result.m_vct.size() > 0) return true;
  for (int i = 0; i < (int)vct_resdel.m_vct.size(); i++) {
    if (IsExist(vct_resdel.m_vct[i])) return true;
  }
  return false;
}

void BestQuoteModel::Update(const CBrokerKeyVector& addKeys,
                            const CBrokerKeyVector& eraseKeys) {
  m_keys->Update(addKeys, eraseKeys);
}
void BestQuoteModel::Sort() {
  if (m_filter.stBlh.nSettlement[0] > CBondContainer::StmAll &&
          m_filter.stBlh.nSettlement[0] <= CBondContainer::StmMax ||
      m_filter.stBlh.nQuotePriceType[0] != CBondContainer::QptAll) {
    BYTE btPriceFilter;
    switch (m_filter.stBlh.nSettlement[0]) {
      case CBondContainer::StmT0:
        btPriceFilter = 0x1;
        break;
      case CBondContainer::StmT1:
        btPriceFilter = 0x2;
        break;
      case CBondContainer::StmFwd:
        btPriceFilter = 0x4;
        break;
      case CBondContainer::StmSpot:
        btPriceFilter = 0x3;
        break;
      default:
        btPriceFilter = 0x0;
        break;
    }

    int sz = sizeof(m_filter.stBlh.nQuotePriceType) / sizeof(int);
    for (int i = 0; i < sz; i++) {
      switch (m_filter.stBlh.nQuotePriceType[i]) {
        case CBondContainer::QptRealoffer:
          btPriceFilter |= 0x10;
          break;
        case CBondContainer::QptPart:
          btPriceFilter |= 0x20;
          break;
        case CBondContainer::QptBargin:
          btPriceFilter |= 0x40;
          break;
        default:
          break;
      }
    }
    m_keys->Sort(btPriceFilter);
  } else
    m_keys->Sort();
}
RowRecordKeyMap& BestQuoteModel::GetRowMap() { return m_row_map; }
